#include <QtGui\QColorDialog>
#include <QtGui\QComboBox>
#include <QtGui\QFileDialog>
#include <QtGui\QToolBar>
#include "MainWindow.h"
#include "MainWindow.ui.h"


// --------------------------------------------------------
//  public: Constructor
// --------------------------------------------------------
MainWindow::MainWindow(QString path)
  : mpForm(new Ui::MainWindow)
{
  mpForm->setupUi(this);
  mCurrentPath = path;

  // Qt Designer doesn't let you add normal widgets to a QToolBar, so we have
  // to add the animations QComboBox manually here.
  cboAnimations = new QComboBox(this);
  cboAnimations->setMinimumWidth(100);
  mpForm->animationToolbar->addWidget(cboAnimations);
  connect(cboAnimations,      SIGNAL(currentIndexChanged(QString)), 
          mpForm->meshWidget, SLOT(changeAnimation(QString)));

  // Now hide the animationToolbar.  It will only show if the loaded mesh has
  // animations.
  mpForm->animationToolbar->hide();

  // Also hide the Material Editor dock by default
  mpForm->editorDock->hide();
}

// --------------------------------------------------------
//  public: Destructor
// --------------------------------------------------------
MainWindow::~MainWindow(void)
{
}

// --------------------------------------------------------
//  public: Load
// --------------------------------------------------------
void MainWindow::load(QString path)
{
  if (!path.isNull())
  {
    // Load the mesh
    mCurrentPath = path;
    mpForm->meshWidget->loadMesh(path);
    
    // Enable the Save and Save As actionms now that something is loaded
    mpForm->actSave->setEnabled(true);
    mpForm->actSaveAs->setEnabled(true);

    // Show a message confirming that the mesh was loaded
    QString fileName = QFileInfo(path).fileName();
    statusBar()->showMessage(QString("loaded %1").arg(fileName), 5000);
  }
}

// --------------------------------------------------------
//  public: Save
// --------------------------------------------------------
void MainWindow::save(QString path)
{
  if (!path.isNull())
  {
    // Save the mesh
    mCurrentPath = path;
    mpForm->meshWidget->saveMesh(path);

    // Show a message confirming that the mesh was saved
    QString fileName = QFileInfo(path).fileName();
    statusBar()->showMessage(QString("saved %1").arg(fileName), 5000);
  }
}

// --------------------------------------------------------
//  public: Load (slot)
// --------------------------------------------------------
void MainWindow::load(void)
{
  // Open load file dialog
  QString path = QFileDialog::getOpenFileName(this, "Select .mesh file to load", QString(), "Ogre mesh files (*.mesh);;*.*");
  if (!path.isNull())
    load(path);
}

// --------------------------------------------------------
//  public: Save (slot)
// --------------------------------------------------------
void MainWindow::save(void)
{
  // If no current path, call saveAs instead
  if (mCurrentPath.isNull())
    saveAs();

  // Otherwise, save to current path
  else
    save(mCurrentPath);
}

// --------------------------------------------------------
//  public: Save As (slot)
// --------------------------------------------------------
void MainWindow::saveAs(void)
{
  QString path = QFileDialog::getSaveFileName(
    this, 
    "Save mesh to file", 
    QString(), 
    "*Ogre mesh files (*.mesh);;*.*");

  if (!path.isNull())
    save(path);
}

// --------------------------------------------------------
//  public: Pick Background Color (slot)
// --------------------------------------------------------
void MainWindow::pickBackgroundColor(void)
{
  static QColorDialog* sColorDialog = NULL;
  if (!sColorDialog) 
  {
    sColorDialog = new QColorDialog(this);
    connect(sColorDialog, SIGNAL(currentColorChanged(QColor)), mpForm->meshWidget, SLOT(changeBackgroundColor(QColor)));
  }

  // Disable the background image
  mpForm->meshWidget->setBackgroundImage(false);

  // Show the color dialog
  sColorDialog->show();
}

// --------------------------------------------------------
//  public: Pick Background Image (slot)
// --------------------------------------------------------
void MainWindow::pickBackgroundImage(void)
{
  static QString filters("Images (*.bmp; *.jpg; *.tiff; *.png);; All Files (*.*)");

  QString path = QFileDialog::getOpenFileName(this, "Select Background Image",
    QString(), filters);
  if (!path.isNull())
  {
    mpForm->meshWidget->setBackgroundImage(true, path);
  }
}

// --------------------------------------------------------
//  public: Show Material Editor (slot)
// --------------------------------------------------------
void MainWindow::showMaterialEditor(void)
{
  mpForm->editorDock->show();   // show
  mpForm->editorDock->raise();  // bring to front
}

// --------------------------------------------------------
//  public: Ogre Setup Complete (slot)
// --------------------------------------------------------
void MainWindow::ogreSetupComplete(void)
{
  // If an initial path was passed into the constructor, load it now
  if (!mCurrentPath.isNull())
    load(mCurrentPath);
}

// --------------------------------------------------------
//  public: On Animations Changed (slot)
// --------------------------------------------------------
void MainWindow::onAnimationsChanged(QStringList animations)
{
  if (animations.empty())
    mpForm->animationToolbar->hide();
  else
  {
    // Show the animation toolbar and update the combo box
    mpForm->animationToolbar->show();
    cboAnimations->clear();
    animations.sort();
    cboAnimations->addItems(animations);
  }

  // Make sure any previous animation is stopped
  mpForm->actAnimStop->trigger();
  mpForm->meshWidget->stopAnimation();
}

// --------------------------------------------------------
//  public: Anim Buttons Changed (slot)
// --------------------------------------------------------
void MainWindow::animButtonsChanged(void)
{
  // Make sure this is a QAction that was triggered
  if (QAction* action = qobject_cast<QAction*>(sender()))
  {
    if (action->isChecked())
    {
      // Uncheck all actions except the one that was triggered
      if (action != mpForm->actAnimPause)
        mpForm->actAnimPause->setChecked(false);
      if (action != mpForm->actAnimPlay)
        mpForm->actAnimPlay->setChecked(false);
      if (action != mpForm->actAnimStop)
        mpForm->actAnimStop->setChecked(false);
    }
    else
    {
      // Cannot uncheck one of these actions manually
      action->setChecked(true);
    }
  }
}

// --------------------------------------------------------
//  public: On Material Editor Visibility Changed (slot)
// --------------------------------------------------------
void MainWindow::onMaterialEditorVisibilityChanged(bool visible)
{
  // Only handle if not maximized
  if (!isMaximized())
  {
    if (visible)
    {
      // Resize the MainWindow to include the size of the dock widget
      resize(width()+mpForm->editorDock->width(), height());
    }
    else
    {
      // Resize the MainWindow to exclude the size of the dock widget
      resize(width()-mpForm->editorDock->width(), height());
    }
  } // end if maximized
}